<script setup>
import List from '../components/List.vue'
import ClusterNamespaceSelector from '../components/ClusterNamespaceSelector.vue'
import { getPodListHandler as getListHandler, deletePodHandler as deleteHandler, deletePodListHandler } from '../../api/pod.js'
import { ElMessage, ElMessageBox  } from 'element-plus'
import { ref, toRefs, reactive, computed, onMounted } from 'vue'
import CodeMirror from '../components/CodeMirror.vue'
import { obj2Yaml } from '../../utils/utils'
// 导入Xterm的样式
import { Terminal } from 'xterm';
import 'xterm/css/xterm.css'
import { FitAddon } from 'xterm-addon-fit'
import { AttachAddon } from 'xterm-addon-attach'


const data = reactive({
  items: [],
  clusterId: "",
  namespace: "",
  deleteItem: "",
  yamlContent: "",
  deleteList: [],
  options: {
    selectionList: [],
    selectionSelected: "",
    selectionOptions: [
      {
        label: "删除",
        value: "Delete"
      },
      {
        label: "强制删除",
        value: "ForceDelete"
      },
    ]
  },
  termOptions: {
    rendererType: "canvas", // 渲染窗口类型
    rows: 15,  // 行数最小高度
    // cols: 100, // 列数
    convertEol: true, // 光标设置为下一行的开头
    cursorBlink: true,// 光标闪烁
    theme: {
      // foreground: 'black', // 前景色黑色
      // background: 'white',  // 背景白色
      lineHeight: 16, 
      cursor: "help"
    }
  }
  
})

// 定义查询pod列表函数
const getList = () => {
  getListHandler(data.clusterId,data.namespace).then(
    (res) => {
      data.items = res.data.data.items
      console.log("pod列表",data.items)
    }
  )
}

// 回调函数传给ClusterNamespaceSelector组件
const rollback = (clusterId,namespace) => {
  data.clusterId = clusterId
  data.namespace = namespace
  getList()
}

const filterTableData = computed(() =>
  data.items.filter(
    (item) =>
      !search.value ||
      item.metadata.name.toLowerCase().includes(search.value.toLowerCase())||
      item.spec.nodeName.toLowerCase().includes(search.value.toLowerCase())||
      item.status.hostIP.toLowerCase().includes(search.value.toLowerCase())
  )
)
const search = ref('')

const deleteItem = (row,force) => {
  console.log("删除pod",row,force)
  ElMessageBox.confirm(
        `名称空间:${data.namespace} Pod: ${row.metadata.name} 确定吗？`,
        'Warning',
        {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
        }
    ).then(() => {
      deleteHandler(data.clusterId,data.namespace,row.metadata.name,force).then(
        (res) => {
          ElMessage({
              message: res.data.message,
              type: 'success',
          })
          getList()
        }
      )
    }).catch(() => {
        return
    })
}

// 判断pod重启次数和状态
const getPodRestartCount = computed(() => (row) => {
  // console.log("row:", row)
  let restartCount = 0
  let readyCount = 0
  let reason = 'Running'
  const containerTotal = row.spec.containers.length
  if (row.status.containerStatuses != undefined) {
    // 获取当前Pod一共有多少个容器
    // containerTotal = row.status.containerStatuses.length
    row.status.containerStatuses.forEach(item => {
      restartCount += item.restartCount
      if (item.ready){
        // 表明当前容器已经启动完成
        readyCount += 1
      } else {
        // 启动失败
        if (item.state.waiting) {
          reason = item.state.waiting.reason
        } else {
          reason = row.status.phase
        }
      }
    })
  } else {
    reason = row.status.phase
    if (row.status.conditions) {
      row.status.conditions.forEach((con)=>{
        if (con.status == 'False') {
          reason = con.reason
        }
      })
    } else {
      reason = row.status.reason
    }
    
  }
  // 1/2 2/2
  const readyStatus = `${readyCount}/${containerTotal}`
  return [restartCount, readyStatus, reason]
})

const showDetail =ref(false)
const detail = (row) => {
  const item = JSON.parse(JSON.stringify(row))
  delete item.metadata.managedFields // 删除maangeFields字段
  // delete metadata.status // 删除status字段
  const itemtemp = {// yaml补上apiVersion字段
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": item.metadata,
    "spec": item.spec
  }
  const yamlData = obj2Yaml(itemtemp)// 当前数据转成yaml
  data.yamlContent = yamlData
  showDetail.value = true

}
const handlerSelectionChange = (selection) => {
  data.options.selectionList = selection
}
const selectionSubmit = () => {
  if(data.options.selectionList.length < 2 || data.options.selectionSelected == "" ) {
    ElMessage.warning("批量操作的Pod不能小于2个,且操作不能为空")
    return
  }
  let msg = ""
  if (data.options.selectionSelected == 'Delete'){
    msg = "确定批量删除多个Pod吗？"
  }else if (data.options.selectionSelected == 'ForceDelete'){
    msg = "确定批量强制删除多个Pod吗？"
  }
  ElMessageBox.confirm(
    msg,
    {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
    }
  ).then(() => {
    data.deleteList = []
    data.options.selectionList.forEach((item) => {
      data.deleteList.push(item.metadata.name)
    })
    console.log("批量删除的数据:", data.deleteList)
    deletePodListHandler(data.clusterId, data.namespace, data.deleteList, data.options.selectionSelected == "ForceDelete").then((res) => {
      ElMessage.success(res.data.message)
      // getList()
    })
  }).catch(() => {
      return
  })
}


let drawer = ref(false)
let currentPod = ref()
let currentContainer = ref()
let curWs = ""
let logContent = ref([])
let currentOption = ref()
let term = ""
let fitAddon = ""
let defaultCommand = "/bin/bash"
onMounted(()=>{
  // 初始化terminal
  term = new Terminal(data.termOptions)
  // fitaddon:窗口自适应
  fitAddon = new FitAddon()
  term.loadAddon(fitAddon)
})
const closeWS = (ws) => {
  ws.close()
  if (currentOption.value == "exec"){
    term.reset()
  }
}
const attachTerm = (ws) => {
  // attachaddon: 建立terminal和WS关联关系,实现ws消息自动管理
  var attachAddon = new AttachAddon(ws)
  const oldSend = attachAddon._sendData;
  attachAddon._sendData = (data) => {
    const wsMessage = JSON.stringify({
      msgType: "input",
      data: data
    })
    return oldSend.call(attachAddon, wsMessage)
  }
  term.loadAddon(attachAddon)
}

const createWS = () => {
  let websocketUrl = ""
  logContent.value = []
  // 1.npm run sit --> ws://127.0.0.1:8080
  // 2.部署后-->拿到当前origin http -> ws https ->wss
  let origin = ""
  if (import.meta.env.MODE == 'sit') {
    origin = "ws://127.0.0.1:8080"
  } else {
    let temp = window.location.origin
    origin = temp.replaceAll('http', 'ws')
  }
  if(currentOption.value == "logs") {
    websocketUrl = `${origin}/api/pod/logs?clusterId=${data.clusterId}&namespace=${data.namespace}&name=${currentPod.value.metadata.name}&container=${currentContainer.value}`
  } else if (currentOption.value == "exec") {
    websocketUrl = `${origin}/api/pod/exec?clusterId=${data.clusterId}&namespace=${data.namespace}&name=${currentPod.value.metadata.name}&container=${currentContainer.value}&defaultCommand=${defaultCommand}`
  }
  let newWs = new WebSocket(websocketUrl);
  newWs.onopen = function(){console.log("链接建立时的事件")}
  newWs.onmessage = function(msgContent) {
    if (currentOption.value == 'logs') {
      // logContent.value.unshift(msgContent.data) //倒序查看
      logContent.value.push(msgContent.data)
    } else if (currentOption.value == 'exec') {
      console.log("接收到的消息",msgContent.data)
      if (defaultCommand == "/bin/bash" && msgContent.data.indexOf("/bin/bash: no such file or directory") != -1) {
        defaultCommand = "/bin/sh"
        const oldWs = curWs
        closeWS(oldWs) //关闭ws
        let newWS = createWS() //重连
        attachTerm(newWS)
        curWs = newWS
      }
    }
  }

  newWs.onerror = function() {
    console.log("链接出现错误的事件")
    ElMessage({
      type: "error",
      message: "无法建立WebSocket链接"
    })
    beforeDrawerClose()
  }
  newWs.onclose = function() {
    console.log("关闭socket链接时的事件")
  }
  return newWs
}
const beforeDrawerClose = () => {
  console.log("关闭socket连接")
  closeWS(curWs)
  if (currentOption.value == "exec"){
    term.dispose() //销毁terminal
  }
  drawer.value = false
}
const logExec = (row, arg) => {
  console.log("查看日志或执行命令:", row.metadata.name)
  currentOption.value = arg
  currentPod.value = row
  currentContainer.value = row.spec.containers[0].name
  const newWs = createWS()
  if (arg == "exec") {attachTerm(newWs)}
  curWs = newWs
  drawer.value = true
}

// const exec = (row) => {
//   console.log("执行命令:",row.metadata.name)
//   currentOption.value = "exec"
//   currentPod.value = row
//   currentContainer.value = row.spec.containers[0].name
//   createWS()
//   drawer.value = true
// }
// const log = (row) => {
//   currentOption.value = "logs"
//   console.log("查看日志:",row.metadata.name)
//   currentPod.value = row
//   currentContainer.value = row.spec.containers[0].name
//   createWS()
//   drawer.value = true
// }

// 更换容器
const containerChanged = () => {
  console.log("当前选择的容器是：",currentContainer.value)
  // 1.断开之前的ws
  const oldWs = curWs
  closeWS(oldWs)
  // 2.重连ws
  let newWs = createWS()
  attachTerm(newWs)
  curWs = newWs
}

const resizeTerm = () => {
  if (drawer.value == false) {return}
  fitAddon.fit()
  const h = window.innerHeight
  const w = window.innerWidth
  const msg = JSON.stringify({
    msgType: "resize",
    cols: w,
    rows: h
  })
  curWs.send(msg)
}
const openDrawer = ()=>{
  if (currentOption.value == 'exec') {
    // 绑定terminal到div
    console.log("绑定Terminal")
    term.open(document.getElementById('terminal'));
    // 调整窗口大小
    resizeTerm()
    window.onresize = (event) =>{
      resizeTerm()
    }
    term.focus()
  }
}
const { yamlContent, options } = toRefs(data)
</script>

<template>
  <List title="Pod列表">
    <template #header-options>
      <ClusterNamespaceSelector @namespaceChangedRollback="rollback">
      </ClusterNamespaceSelector>
      <el-input v-model="search" size="small" placeholder="搜索" style="width: 140px; margin-left: 10px; height: 32px;" />
    </template>
    <template #main>
      <el-table
      border
      height="480"
      :data="filterTableData"
      style="width: 100%"
      :default-sort="{prop:'metadata.creationTimestamp',order:'descending'}"
      @selection-change="handlerSelectionChange"
      >
        <el-table-column type="selection" width="35"/>
        <el-table-column fixed prop="" align="center" label="名称" width="220">
          <template #default="scope">
            <el-button link type="primary"  @click="detail(scope.row)">{{ scope.row.metadata.name }}</el-button>
          </template>
        </el-table-column>
        <el-table-column prop="metadata.creationTimestamp" align="center" label="创建时间" width="180" sortable/>
        <el-table-column prop="metadata.namespace" align="center" label="命名空间" width="120" />

        <el-table-column prop="" align="center" label="状态" width="150" sortable>
          <template #default="scope">
            <span style="color: red;" v-if="scope.row.metadata.deletionTimestamp">Terminating</span>
            <span style="color: red;" v-else-if="!scope.row.status.containerStatuses" :title="JSON.stringify(scope.row.status) ">{{ scope.row.status.phase }}</span>
            <template v-else>
              <el-tag :type="getPodRestartCount(scope.row)[2] == 'Running'?'success':'primary'"
              :title="JSON.stringify(scope.row.status.initContainerStatuses) + '\n' + JSON.stringify(scope.row.status.containerStatuses) + '\n' + JSON.stringify(scope.row.status.conditions)">
                {{getPodRestartCount(scope.row)[2]}}
              </el-tag>
            </template>
            <!-- <span v-if="scope.row.status.phase == 'Running'">
               <el-tag type="success">{{ scope.row.status.phase }}</el-tag>
            </span>
            <span v-else-if="scope.row.status.phase == 'Pending'">
              <el-tag type="warning">{{ scope.row.status.phase }}</el-tag>
            </span>
            <span v-else-if="scope.row.status.phase == 'Terminated'">
              <el-tag type="danger">{{ scope.row.status.phase }}</el-tag>
            </span>
            <span v-else>
              <el-tag type="danger">{{ scope.row.status.phase }}</el-tag>
            </span> -->
          </template>
        </el-table-column>

        <el-table-column prop="" align="center" label="容器状态" width="85">
          <template #default="scope">
            <span v-if="!scope.row.metadata.deletionTimestamp">{{ getPodRestartCount(scope.row)[1] }}</span>
          </template>
        </el-table-column>

        <el-table-column prop="" align="center" label="重启次数" width="85">
          <template #default="scope">
            <span v-if="!scope.row.metadata.deletionTimestamp">{{ getPodRestartCount(scope.row)[0] }}</span>
          </template>
        </el-table-column>



        <el-table-column prop="status.podIP" align="center" label="Pod IP" width="130"></el-table-column>
        <el-table-column prop="spec.nodeName" align="center" label="宿主机名" width="190"></el-table-column>
        <el-table-column prop="status.hostIP" align="center" label="宿主机IP" width="130"></el-table-column>



        <el-table-column fixed="right" align="center" label="操作" width="320">
          <template #default="scope">
            <el-button v-if="!scope.row.metadata.deletionTimestamp" link type="warning" @click="deleteItem(scope.row,false)">删除</el-button>
            <el-button v-else link type="warning" @click="deleteItem(scope.row,true)">强制删除</el-button>
            <el-button v-if="!scope.row.metadata.deletionTimestamp" link type="primary" @click="logExec(scope.row, 'exec')">执行命令</el-button>
            <el-button v-if="!scope.row.metadata.deletionTimestamp" link type="info" @click="logExec(scope.row, 'logs')">查看日志</el-button>
          </template>
        </el-table-column>
      </el-table>
    </template>
    <template #footer-left>
      <el-select v-model="options.selectionSelected" placeholder="批量操作选项" style="width: 140px;margin-right: 10px;">
        <el-option v-for="item in options.selectionOptions" :key="item.value" :label="item.label" :value="item.value"/>
      </el-select>
      <el-button type="warning" @click="selectionSubmit()">确定</el-button>
    </template>
    <template #footer-right>
      <span>总数:{{ filterTableData.length }}</span>
    </template>

  </List>
  <el-dialog
    destroy-on-close 
    v-model="showDetail" 
    width="70%">
      <template #header="{titleId,titleClass}">
        <div class="my-header">
          <div :id="titleId" :class="titleClass">
            <el-button type="primary" size="large" title="资源所在集群">
              <i class="iconfont icon-k8s" style="font-size: 20px"/>
              <span style="font-size: 20px;margin-left: 10px;">{{ data.clusterId }}</span>
            </el-button>
            <el-button type="primary" size="large" title="资源所在空间">
              <i class="iconfont icon-k8s" style="font-size: 20px"/>
              <span style="font-size: 20px;margin-left: 10px;">{{ data.namespace }}</span>
            </el-button>
          </div>
        </div>
      </template>
      <CodeMirror
      height="600px"
      v-model="yamlContent"
      ></CodeMirror>
  </el-dialog>
  <el-drawer
    v-model="drawer"
    direction="btt"
    size="40%"
    :with-header="false"
    @opened="openDrawer"
    :before-close="beforeDrawerClose"
  >
    <!-- title -->
    <div style="display: flex;">
      <!-- Pod名称 -->
      <el-icon :size="40"><i class="iconfont icon-pod" style="font-size: 30px;"></i></el-icon>
      <span style="margin-left: 10px; margin-top: auto; margin-bottom: auto;">{{ currentPod.metadata.name }}</span>
      <el-radio-group v-model="currentContainer" style="margin-left: 20px;">
        <el-radio @change="containerChanged()" size="large" v-for="c in currentPod.spec.containers" :value="c.name">{{ c.name }}</el-radio>
      </el-radio-group>
    </div>
    <!-- 日志或者执行命令 -->
    <div>
      <template v-if="currentOption == 'logs'">
        <!-- <span class="algLog" style="text-align:left;display: block;" v-for="line in logContent">{{ line }}</span> -->
        <!-- 使用table展示 -->
        <el-table :data="logContent" style="width:100%" size="small">
          <el-table-column>
            <template #default="scope">
              {{ scope.row }}
            </template>
          </el-table-column>
        </el-table>
      </template>
      <template v-else-if="currentOption == 'exec'">
        <div id="terminal" style="text-align: left;"></div>
      </template>
    </div>
  </el-drawer>
</template>

<style scoped>
</style>
